﻿module Combinator_LL_Parser
//open System
//open Ast
//
//type ILabel = int
//type Pos = int
//type PosSet = Set<int>
//type R = Pos -> PosSet
//
//type a = int
//
//type State = Map<int, Map<int, PosSet>>
//and StateM<'t, 's> = StateM of ('s -> 't * 's)
//                      interface System.IComparable with 
//                            member x.CompareTo yobj = 
//                              match yobj with 
//                              | :? StateM<'t,'s> as y -> compare x y
//                              | _ -> invalidArg "yobj" "cannot compare values of different types"
//
//
//and RM = Pos -> StateM<PosSet, State>
//
//type StateBuilder() =
//  member this.Bind(p : StateM<'u, 's>, k:'u -> StateM<'t, 's>) : StateM<'t, 's> =
//    StateM(
//      fun s -> let (StateM(p)) = p
//               let x,s' = p s
//               let (StateM(k)) = k x
//               in (k s'))
//  member this.Return (a:'t) : StateM<'t,'s> = StateM(fun s -> a,s)
//
//let state = StateBuilder()
//let get : StateM<'s,'s> = StateM(fun s -> s,s)
//let modify s' : StateM<'t,'s>  = StateM(fun _ -> (),s')
//
//let (<+>) : RM -> RM -> RM =
//  fun p q r -> 
//    state{
//      let! end_p = p r
//      let! end_q = q r
//      return Set.union end_p end_q
//    }
//let rec monadM lst_monads =
//  state{
//    match lst_monads with
//    [] -> return []
//    |x::xs -> 
//      let! x = x
//      let! xs = monadM xs
//      return (x::xs)
//  }
//
//let (|*>) =
//  fun (p:RM) (q:RM)  r -> 
//    state{
//      let! end_p = p  r
//      let end_qs = Seq.map (fun r -> q r) end_p |> Seq.toList
//      let! end_qs = monadM end_qs
//      return (Set.unionMany end_qs)
//    }
//
//let lookupT (name:int) (input:int) (mTable:State) =
//  let inner = mTable.TryFind name
//  match inner with
//  None -> None
//  |Some inner ->
//    let memo = inner.TryFind name
//    match memo with
//    None -> None
//    |Some stored -> Some stored
//
//let memoize i_name parser : RM =  
//  fun pos ->
//    let update_table res (mt:State) =
//      let singleton = Map [pos,res]
//      match mt.TryFind(i_name) with
//      None -> mt.Add(i_name,singleton)
//      |Some value -> 
//        let posSet = mt.[i_name]
//        mt.Add(i_name,posSet.Add(pos,res))
//
//    state{
//      let! mt = get
//      match lookupT i_name pos mt with
//      Some res -> return res
//      |None ->
//        let! res = parser pos
//        do! modify (update_table res mt)
//        return res
//    }
//
//
//
//let parse : R -> PosSet = 
//  fun p -> p 0
//
